package com.cls.business.service.impl;

import com.cls.business.entity.*;
import com.cls.business.mapper.ReviewMapper;
import com.cls.business.mapper.TopicMapper;
import com.cls.business.mapper.TopicPlanMapper;
import com.cls.business.service.*;
import com.cls.business.vo.DeclareVo;
import com.cls.common.entity.QueryRequest;
import com.cls.business.mapper.DeclareEntrustMapper;
import com.cls.common.enums.DictEnum;
import com.cls.common.enums.EmailTextEnum;
import com.cls.common.utils.EmailSenderUtil;
import com.cls.system.entity.User;
import com.cls.system.service.ISysFileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import lombok.RequiredArgsConstructor;
import com.github.pagehelper.PageHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;

/**
 * 委托课题信息附表 Service实现
 *
 * @author slx
 * @date 2020-12-02 14:25:22
 */
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class DeclareEntrustServiceImpl extends ServiceImpl<DeclareEntrustMapper, DeclareEntrust> implements IDeclareEntrustService {

    @Autowired
    private IEntrustCheckLogService entrustCheckLogService;

    private final IApplicantInfoService applicantInfoService;
    @Autowired
    private IMemberInfoRecordService memberInfoRecordService;
    @Autowired
    private IMemberInfoService memberInfoService;
    @Autowired
    private IDelayApplyService delayApplyService;
    @Autowired
    private IMessageService iMessageService;
    private final INoticeService noticeService;

    //发送邮箱
    private final EmailSenderUtil emailSenderUtil;
    private final TopicMapper topicMapper;
    private final TopicPlanMapper topicPlanMapper;
    private final ISysFileService sysFileService;
    private final IMaxIndexService maxIndexService;


    @Override
    public PageInfo<DeclareEntrust> findDeclareEntrusts(QueryRequest request, DeclareEntrust declareEntrust) {
        LambdaQueryWrapper<DeclareEntrust> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<DeclareEntrust> list= this.list(queryWrapper);
        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }
    @Override
    public PageInfo<DeclareVo> findDeclareEntrustPage(QueryRequest request, DeclareVo declareVo) {

        PageHelper.startPage(request.getPageNum(), request.getPageSize());


        List<DeclareVo> list= this.baseMapper.findDeclareEntrustPage(declareVo);
        //结项结果状态和结项通知公告发布
        /*for (DeclareVo one : list) {
            DeclareTopic declareTopicById = this.baseMapper.getDeclareTopicById(one.getDeclareId());
             if(declareTopicById.getApplyCount()!=null){
                 DeclarePlan declarePlan=this.baseMapper.findPlan(one.getDeclareId(),declareTopicById.getApplyCount());
                 if(declarePlan!=null){
                     TopicPlan topicPlan = topicPlanMapper.selectById(declarePlan.getPlanId());
                     if (topicPlan != null) {
                         one.setConcludeCode(topicPlan.getStatusCode());
                         //结项通知公告
                         one.setIsPreItemNotice(false);
                         Long preItemNoticeId = topicPlan.getConcludeFinishNoticeId();
                         if (preItemNoticeId != null) {
                          Notice notice = Optional.of(noticeService.getById(preItemNoticeId)).orElseGet(()->new Notice());
                          one.setIsPreItemNotice(notice.getIsPublish());
                           if(!notice.getIsPublish()){
                               if(one.getStatusTypeCode().equals(DictEnum.CONCLUDE_PASSED.getCode())||one.getStatusTypeCode().equals(DictEnum.CONCLUDE_FAILED.getCode())){
                                   code=DictEnum.CONCLUDE_APPLY.getCode();
                               }
                           }
                          }else {
                             if(one.getStatusTypeCode().equals(DictEnum.CONCLUDE_PASSED.getCode())||one.getStatusTypeCode().equals(DictEnum.CONCLUDE_FAILED.getCode())){
                                 one.setExamine(DictEnum.CONCLUDE_APPLY.getCode());
                             }
                         }
                     }
                 }
             }
        }*/
        //状态
        for (DeclareVo dvo:list) {
            String code=null;
            //结项结果状态和结项通知公告发布状态
            DeclareTopic declareTopicById = this.baseMapper.getDeclareTopicById(dvo.getDeclareId());
            if(declareTopicById.getApplyCount()!=null){
                DeclarePlan declarePlan=this.baseMapper.findPlan(dvo.getDeclareId(),declareTopicById.getApplyCount());
                if(declarePlan!=null){
                    TopicPlan topicPlan = topicPlanMapper.selectById(declarePlan.getPlanId());
                    if (topicPlan != null) {
                        dvo.setConcludeCode(topicPlan.getStatusCode());
                        //结项通知公告
                        dvo.setIsPreItemNotice(false);
                        Long preItemNoticeId = topicPlan.getConcludeFinishNoticeId();
                        if (preItemNoticeId != null) {
                            Notice notice = Optional.of(noticeService.getById(preItemNoticeId)).orElseGet(()->new Notice());
                            dvo.setIsPreItemNotice(notice.getIsPublish());
                            if(!notice.getIsPublish()){
                                if(dvo.getStatusTypeCode().equals(DictEnum.CONCLUDE_PASSED.getCode())||dvo.getStatusTypeCode().equals(DictEnum.CONCLUDE_FAILED.getCode())){
                                    code=DictEnum.CONCLUDE_APPLY.getCode();
                                }
                            }
                        }else {
                            if(dvo.getStatusTypeCode().equals(DictEnum.CONCLUDE_PASSED.getCode())||dvo.getStatusTypeCode().equals(DictEnum.CONCLUDE_FAILED.getCode())){
                                code=DictEnum.CONCLUDE_APPLY.getCode();
                            }
                        }
                    }
                }
            }

            if((dvo.getExamine().equals(DictEnum.INFO_PASSED.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.APPLY.getCode())))||
                    (dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())&&dvo.getExamine().equals(DictEnum.INFO_FAILED.getCode()))||
                    (dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())&&dvo.getExamine().equals(DictEnum.INFO_WAIT.getCode()))||
                    (dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())&&dvo.getExamine().equals(DictEnum.INFO_PASSED.getCode()))
            ) {
                dvo.setProcessCode(dvo.getExamine());
            }else {
                dvo.setProcessCode(dvo.getStatusTypeCode());
            }
            if((dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode()))&&StringUtils.isBlank(dvo.getExamine())){
                dvo.setProcessCode(dvo.getStatusTypeCode());
            }
           if((dvo.getExamine().equals(DictEnum.INFO_NO.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())))||
               (dvo.getExamine().equals(DictEnum.INFO_WAIT.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())))||
               (dvo.getExamine().equals(DictEnum.INFO_PASSED.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.APPLY.getCode())))||
               (dvo.getExamine().equals(DictEnum.INFO_FAILED.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())))
           ) { }else {
               dvo.setExamine(dvo.getStatusTypeCode());
           }
           if(dvo.getProcessCode().equals(DictEnum.CONCLUDE_ASSIGN.getCode())||
            dvo.getProcessCode().equals(DictEnum.CHECK_PASSED_REVIEW.getCode())
           ){
               dvo.setProcessCode(DictEnum.CONCLUDE_APPLY.getCode());
           }
           if(StringUtils.isNotBlank(code)){
               dvo.setProcessCode(code);
           }
        }

        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }
    @Override
    public PageInfo<DeclareVo> findDeclareEntrustPageOrder(QueryRequest request, DeclareVo declareVo) {

        PageHelper.startPage(request.getPageNum(), request.getPageSize());

        List<DeclareVo> list= this.baseMapper.findDeclareEntrustPageOrder(declareVo);
        //结项结果状态
        for (DeclareVo one : list) {

            DeclareTopic declareTopicById = this.baseMapper.getDeclareTopicById(one.getDeclareId());
            if(declareTopicById.getApplyCount()!=null){
                DeclarePlan declarePlan=this.baseMapper.findPlan(one.getDeclareId(),declareTopicById.getApplyCount());
                if(declarePlan!=null){
                    TopicPlan topicPlan = topicPlanMapper.selectById(declarePlan.getPlanId());
                    if (topicPlan != null) {
                        one.setConcludeCode(topicPlan.getStatusCode());
                    }
                }
            }
        }
        //状态
        for (DeclareVo dvo:list) {
            if((dvo.getExamine().equals(DictEnum.INFO_PASSED.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.APPLY.getCode())))||
                    (dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())&&dvo.getExamine().equals(DictEnum.INFO_FAILED.getCode()))||
                    (dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())&&dvo.getExamine().equals(DictEnum.INFO_WAIT.getCode()))||
                    (dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())&&dvo.getExamine().equals(DictEnum.INFO_PASSED.getCode()))
            ) {
                dvo.setProcessCode(dvo.getExamine());
            }else {
                dvo.setProcessCode(dvo.getStatusTypeCode());
            }
            if((dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode()))&&StringUtils.isBlank(dvo.getExamine())){
                dvo.setProcessCode(dvo.getStatusTypeCode());
            }

            if((dvo.getExamine().equals(DictEnum.INFO_NO.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())))||
                    (dvo.getExamine().equals(DictEnum.INFO_WAIT.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())))||
                    (dvo.getExamine().equals(DictEnum.INFO_PASSED.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.APPLY.getCode())))||
                    (dvo.getExamine().equals(DictEnum.INFO_FAILED.getCode())&&(dvo.getStatusTypeCode().equals(DictEnum.NO_APPLY.getCode())))
            ) { }else {
                dvo.setExamine(dvo.getStatusTypeCode());
            }
        }

        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }
    @Override
    public List<DeclareEntrust> findDeclareEntrusts(DeclareEntrust declareEntrust) {
	    LambdaQueryWrapper<DeclareEntrust> queryWrapper = new LambdaQueryWrapper<>();
		// TODO 设置查询条件
		return this.baseMapper.selectList(queryWrapper);
    }
    @Override
    public DeclareEntrust findByDeclareId(Long declareId) {

        return this.baseMapper.findByDeclareId(declareId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createDeclareEntrust(DeclareEntrust declareEntrust) {
        this.save(declareEntrust);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDeclareEntrust(DeclareEntrust declareEntrust) {
        this.saveOrUpdate(declareEntrust);
    }

    private synchronized String getMaxIndex(MaxIndex maxIndex) {
        //查看有没有这中类型的
        List<MaxIndex> maxIndexs = maxIndexService.findMaxIndex(maxIndex);
        if (maxIndexs == null || maxIndexs.size() < 1) {
            maxIndex.setMaxNum(1);
            maxIndexService.createMaxIndex(maxIndex);
        } else if (maxIndexs.size() == 1) {
            maxIndex = maxIndexs.get(0);
        } else {
            throw new IllegalArgumentException("获取序列号失败！");
        }
        int maxNum = maxIndex.getMaxNum();
        maxIndex.setMaxNum(maxNum + 1);
        maxIndexService.updateMaxIndex(maxIndex);
        return String.format("-%d", maxNum);
    }

    /**
    * 删除
    * @param ids
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDeclareEntrusts(String[] ids) {
        List< String > list = Arrays.asList(ids);
        this.removeByIds(list);
     }

    /**
     * 委托课题信息审核
     * @param declareTopic
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCheckEntrust(DeclareTopic declareTopic,User adminUser, MaxIndex maxIndex) {
        //修改课题
        DeclareEntrust declareEntrust =new DeclareEntrust();
        //课题id
        declareEntrust.setDeclareId(declareTopic.getDeclareId());
        //评审类型
        declareEntrust.setExamine(declareTopic.getStatusTypeCode());
        this.baseMapper.updateCheck(declareEntrust);
        DeclareTopic topicId = this.baseMapper.getDeclareTopicById(declareTopic.getDeclareId());
        String statusName="审核不通过";
        if(DictEnum.INFO_PASSED.getCode().equals(declareTopic.getStatusTypeCode())){
            //如果通过话主表修改状态
            statusName="审核通过";
            DeclareTopic declareTopicById = new DeclareTopic();
            declareTopicById.setDeclareId(declareTopic.getDeclareId());
            declareTopicById.setStatusTypeCode(DictEnum.APPLY.getCode());
            //生成立项编号
           // CLS(年份)委托课题类别+序号，重点委托ZDWT  重点专项ZDZX  委托WT
            Topic topic = topicMapper.selectById(topicId.getTopicId());
            String year=null;
            if(topic!=null){
                year = topic.getYear();
            }
            //获取编号
            String index = getMaxIndex(maxIndex);
            String code="CLS("+year+")"+topicId.getLevelTypeCode()+index;
            //declareTopicById.setCode(code);
            declareTopicById.setItemCode(code);
            this.baseMapper.updateDeclareTipic(declareTopicById);
        }
        //新增审核记录
        EntrustCheckLog entrustCheckLog=new EntrustCheckLog();
        entrustCheckLog.setCheckType(declareTopic.getStatusTypeCode());
        entrustCheckLog.setReason(declareTopic.getCheckResult());
        entrustCheckLog.setCheckName(adminUser.getUsername());
        entrustCheckLog.setDeclareId(declareTopic.getDeclareId());
        entrustCheckLogService.createEntrustCheckLog(entrustCheckLog);
        //发送消息和邮箱 ----信息审核============================================
        String contenxt = String.format(EmailTextEnum.INFO_APPLY_TEXT.getText(), topicId.getName(), statusName);
        Long applicantId = topicId.getApplicantId();
        ApplicantInfo applicantInfo = applicantInfoService.getById(applicantId);
        iMessageService.sendMessageById(contenxt,adminUser,applicantInfo.getUserId());
        //邮箱
        if(StringUtils.isNotBlank(applicantInfo.getEmail())){
            emailSenderUtil.sendEmail(EmailTextEnum.INFO_CHECK_APPLY.getText(), contenxt, applicantInfo.getEmail());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCheckMember(DeclareTopic declareTopic, User adminUser) {

        MemberInfoRecord memberInfoRecord =new MemberInfoRecord();
        memberInfoRecord.setDeclareId(declareTopic.getDeclareId());
        memberInfoRecord.setMemberType(1);
        List<MemberInfoRecord> memberInfoRecordList = memberInfoRecordService.findMemberInfoRecords(memberInfoRecord);
        DeclareTopic declareTopicFind = this.baseMapper.getDeclareTopicById(declareTopic.getDeclareId());
        String statusName="审核不通过";
        if(DictEnum.CHANGE_PASSED.getCode().equals(declareTopic.getStatusTypeCode())){
            //通过修改数据并且删除审核数据
            //修改申请人工作单位
            statusName="审核通过";
            DeclareEntrust declareEntrust = this.baseMapper.findByDeclareId(declareTopic.getDeclareId());
            Long applicantId = declareTopicFind.getApplicantId();
            ApplicantInfo applicantInfo=new ApplicantInfo();
            applicantInfo.setApplicantId(applicantId);
            applicantInfo.setCompany(declareEntrust.getChangeCompany());
            applicantInfoService.saveOrUpdate(applicantInfo);
            //修改成员信息
            memberInfoRecordList.forEach(item ->{
                MemberInfo memberInfo = item.convertToMemberInfo();
                if(DictEnum.MEMBER_ADD.getCode().equals(item.getOperationCode())){
                    //新增
                    memberInfoService.createMemberInfo(memberInfo);

                }else if(DictEnum.MEMBER_DEL.getCode().equals(item.getOperationCode())){
                    //删除
                    memberInfoService.removeById(memberInfo.getMemberId());

                }else if(DictEnum.MEMBER_UPDATE.getCode().equals(item.getOperationCode())){
                    //修改
                    memberInfoService.updateMemberInfo(memberInfo);
                }
            });
        }
        //最后删除记录信息
        memberInfoRecordList.forEach(item ->{
            memberInfoRecordService.removeById(item.getMemberRecordId());
        });

        //修改课题
        DeclareEntrust declareEntrust =new DeclareEntrust();
        //课题id
        declareEntrust.setDeclareId(declareTopic.getDeclareId());
        //评审类型
        declareEntrust.setExamineChange(declareTopic.getStatusTypeCode());
        baseMapper.updateCheck(declareEntrust);
        //更新审核记录
        EntrustCheckLog entrustCheckLog=new EntrustCheckLog();
        entrustCheckLog.setCheckType(declareTopic.getStatusTypeCode());
        entrustCheckLog.setReason(declareTopic.getCheckResult());
        entrustCheckLog.setCheckName(adminUser.getUsername());
        entrustCheckLog.setDeclareId(declareTopic.getDeclareId());
        entrustCheckLogService.createEntrustCheckLog(entrustCheckLog);
        //发送消息和邮箱 ----信息变更===================================================================
        String contenxt = String.format(EmailTextEnum.CHANGE_APPLY_TEXT.getText(),declareTopicFind.getName(), statusName);
        //根据申请人id找用户id
        Long applicantId = declareTopicFind.getApplicantId();
        ApplicantInfo applicantInfo = applicantInfoService.getById(applicantId);
       iMessageService.sendMessageById(contenxt,adminUser,applicantInfo.getUserId());
        //邮箱
        if(StringUtils.isNotBlank(applicantInfo.getEmail())){
            emailSenderUtil.sendEmail(EmailTextEnum.CHANGE_APPLY.getText(), contenxt, applicantInfo.getEmail());
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCheckDelay(DeclareTopic declareTopic,User adminUser) {
        //修改课题
        DeclareEntrust declareEntrust =new DeclareEntrust();
        //课题id
        declareEntrust.setDeclareId(declareTopic.getDeclareId());
        //评审类型
        declareEntrust.setExamineDelay(declareTopic.getStatusTypeCode());
        baseMapper.updateCheck(declareEntrust);
        //更新延期申请表审核类型
        DelayApply delayApply=new DelayApply();
        delayApply.setDelayApplyId(declareTopic.getDelayApplyId());
        delayApply.setExamineDelay(declareTopic.getStatusTypeCode());
        delayApplyService.updateDelayApply(delayApply);
        //更新审核记录
        EntrustCheckLog entrustCheckLog=new EntrustCheckLog();
        entrustCheckLog.setCheckType(declareTopic.getStatusTypeCode());
        entrustCheckLog.setReason(declareTopic.getCheckResult());
        entrustCheckLog.setCheckName(adminUser.getUsername());
        entrustCheckLog.setDeclareId(declareTopic.getDeclareId());
        entrustCheckLogService.createEntrustCheckLog(entrustCheckLog);
        //发送消息和邮箱 ----延期申请====================================================
        String statusName="审核不通过";
        if(DictEnum.DELAY_PASSED.getCode().equals(declareTopic.getStatusTypeCode())){
            statusName="审核通过";
        }
        DeclareTopic declareTopicInfo = this.baseMapper.getDeclareTopicById(declareTopic.getDeclareId());
        String contenxt = String.format(EmailTextEnum.DELAY_CHECK_APPLY_TEXT.getText(),declareTopicInfo.getName(), statusName);
        //根据申请人id找用户id
        Long applicantId = declareTopicInfo.getApplicantId();
        ApplicantInfo applicantInfo = applicantInfoService.getById(applicantId);
        iMessageService.sendMessageById(contenxt,adminUser,applicantInfo.getUserId());

        //邮箱
        if(StringUtils.isNotBlank(applicantInfo.getEmail())){
            emailSenderUtil.sendEmail(EmailTextEnum.DELAY_CHECK_APPLY.getText(), contenxt, applicantInfo.getEmail());
        }

    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyDelayApply(DelayApply delayApply) {
        //删除以前申请记录
        Map<String, Object> columnMap =new HashMap<>();
        columnMap.put("declare_id",delayApply.getDeclareId());
        delayApplyService.removeByMap(columnMap);

        DeclareEntrust declareEntrust =new DeclareEntrust();
        declareEntrust.setDeclareId(delayApply.getDeclareId());
        declareEntrust.setExamineDelay(DictEnum.DELAY_WAIT.getCode());
        this.baseMapper.updateCheck(declareEntrust);

        //附件标识
        sysFileService.updateIsFinish(delayApply.getDelayFileId(),null);
        //新增延期申请
        delayApplyService.createDelayApply(delayApply);
    }

}
